<template>
  <div class="echart" ref="mychart" v-loading="loading"></div>
</template>

<script>
import * as echarts from "echarts";

export default {
  name: "EchartsComponent",
  props: {
    options: {
      type: Object,
      default: () => ({
        title: {
          text: "ECharts 示例",
        },
        tooltip: {},
        legend: {
          data: ["销量"],
        },
        xAxis: {
          data: ["类型一", "类型二", "类型三", "类型四", "类型五", "类型六"],
        },
        yAxis: {},
        series: [
          {
            name: "销量",
            type: "bar",
            data: [5, 20, 36, 10, 10, 20],
          },
        ],
      }),
    },
    // 是否自动响应窗口大小变化
    autoResize: {
      type: Boolean,
      default: true,
    },
    // 图表主题
    theme: {
      type: String,
      default: "default",
    },
    // 图表初始化选项
    initOptions: {
      type: Object,
      default: () => ({}),
    },
    // 是否显示加载状态
    loading: {
      type: Boolean,
      default: false,
    },
    // 加载状态配置
    loadingOptions: {
      type: Object,
      default: () => ({
        text: "数据加载中...",
        color: "#409EFF",
        textColor: "#000",
        maskColor: "rgba(255, 255, 255, 0.8)",
        zlevel: 0,
      }),
    },
    // 防抖延迟时间（毫秒）
    resizeDebounce: {
      type: Number,
      default: 300,
    },
    // 图表容器的最小高度
    minHeight: {
      type: String,
      default: "400px",
    },
  },
  data() {
    return {
      myChart: null,
      resizeTimer: null,
    };
  },
  computed: {
    // 动态样式
    chartStyle() {
      return {
        width: "100%",
        height: "100%",
        minHeight: this.minHeight,
      };
    },
  },
  watch: {
    // 监听 options 的变化，实时更新图表
    options: {
      handler(newOptions) {
        if (this.myChart && newOptions) {
          this.updateChart(newOptions);
        }
      },
      deep: true,
    },
    // 监听主题变化
    theme: {
      handler(newTheme) {
        if (this.myChart) {
          this.reinitChart();
        }
      },
    },
    // 监听加载状态
    loading: {
      handler(isLoading) {
        if (this.myChart) {
          if (isLoading) {
            this.myChart.showLoading(this.loadingOptions);
          } else {
            this.myChart.hideLoading();
          }
        }
      },
      immediate: true,
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.initEcharts();
      if (this.autoResize) {
        this.addResizeListener();
      }
    });
  },
  methods: {
    // 初始化图表
    initEcharts() {
      try {
        if (!this.$refs.mychart) {
          console.error("ECharts: 图表容器未找到");
          return;
        }

        // 如果已存在实例，先销毁
        if (this.myChart) {
          this.myChart.dispose();
        }

        // 初始化图表实例
        this.myChart = echarts.init(this.$refs.mychart, this.theme, this.initOptions);

        // 设置图表配置
        this.updateChart(this.options);

        // 设置加载状态
        if (this.loading) {
          this.myChart.showLoading(this.loadingOptions);
        }

        // 绑定图表事件
        this.bindEvents();

        // 触发初始化完成事件
        this.$emit("chart-ready", this.myChart);
      } catch (error) {
        console.error("ECharts 初始化失败:", error);
        this.$emit("chart-error", error);
      }
    },

    // 更新图表配置
    updateChart(options) {
      if (!this.myChart || !options) return;

      try {
        this.myChart.setOption(options, true);
        this.$emit("chart-updated", this.myChart);
      } catch (error) {
        console.error("ECharts 更新失败:", error);
        this.$emit("chart-error", error);
      }
    },

    // 重新初始化图表（主题变化时使用）
    reinitChart() {
      if (this.myChart) {
        this.myChart.dispose();
        this.myChart = null;
      }
      this.initEcharts();
    },

    // 绑定图表事件
    bindEvents() {
      if (!this.myChart) return;

      // 绑定点击事件
      this.myChart.on("click", (params) => {
        this.$emit("chart-click", params);
      });

      // 绑定双击事件
      this.myChart.on("dblclick", (params) => {
        this.$emit("chart-dblclick", params);
      });

      // 绑定鼠标悬停事件
      this.myChart.on("mouseover", (params) => {
        this.$emit("chart-mouseover", params);
      });

      // 绑定鼠标离开事件
      this.myChart.on("mouseout", (params) => {
        this.$emit("chart-mouseout", params);
      });

      // 绑定数据区域缩放事件
      this.myChart.on("datazoom", (params) => {
        this.$emit("chart-datazoom", params);
      });
    },

    // 添加窗口大小变化监听器（带防抖）
    addResizeListener() {
      window.addEventListener("resize", this.debouncedResize);
    },

    // 防抖的resize处理函数
    debouncedResize() {
      if (this.resizeTimer) {
        clearTimeout(this.resizeTimer);
      }
      this.resizeTimer = setTimeout(() => {
        this.handleResize();
      }, this.resizeDebounce);
    },

    // 处理窗口大小变化
    handleResize() {
      if (this.myChart) {
        try {
          this.myChart.resize();
          this.$emit("chart-resized", this.myChart);
        } catch (error) {
          console.error("ECharts resize 失败:", error);
        }
      }
    },

    // 手动触发图表重绘
    resize() {
      this.handleResize();
    },

    // 获取图表实例
    getChart() {
      return this.myChart;
    },

    // 获取图表数据URL（用于导出）
    getDataURL(options = {}) {
      if (!this.myChart) return null;

      const defaultOptions = {
        type: "png",
        pixelRatio: 1,
        backgroundColor: "#fff",
      };

      return this.myChart.getDataURL({ ...defaultOptions, ...options });
    },

    // 清空图表
    clear() {
      if (this.myChart) {
        this.myChart.clear();
      }
    },

    // 显示加载动画
    showLoading(options = {}) {
      if (this.myChart) {
        this.myChart.showLoading({ ...this.loadingOptions, ...options });
      }
    },

    // 隐藏加载动画
    hideLoading() {
      if (this.myChart) {
        this.myChart.hideLoading();
      }
    },
  },

  beforeDestroy() {
    try {
      // 清除定时器
      if (this.resizeTimer) {
        clearTimeout(this.resizeTimer);
        this.resizeTimer = null;
      }

      // 移除事件监听器
      if (this.autoResize) {
        window.removeEventListener("resize", this.debouncedResize);
      }

      // 销毁图表实例
      if (this.myChart) {
        this.myChart.dispose();
        this.myChart = null;
      }
    } catch (error) {
      console.error("ECharts 销毁失败:", error);
    }
  },
};
</script>

<style scoped>
.echart {
  width: 100%;
  height: 100%;
  position: relative;
}

/* 确保容器有最小高度，防止图表无法显示 */
.echart:empty::before {
  content: "";
  display: block;
  min-height: 400px;
}
</style>
